home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / xview / genial / func / line.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-14  |  6.5 KB  |  293 lines

  1. /*
  2.  * line.c -- routines for drawing line regions
  3.  */
  4.  
  5. #include "common.h"
  6. #include "llist.h"
  7. #include "reg.h"
  8. #include "display.h"
  9. #include "ui.h"
  10. #include <X11/Xlib.h>
  11. #include <stdio.h>
  12.  
  13. /* Keep a huge buffer that way we only have to malloc and bcopy() at the
  14.    end of the sleection process */
  15.  
  16. #define PVEC_SIZE 1450
  17.  
  18. static struct pval pvec[PVEC_SIZE];    /* temporary buffer for storing
  19.                      * points */
  20.  
  21. /* draw_line() actually draws a line from the region */
  22. draw_line(reg)
  23.     struct region *reg;
  24. {
  25.     struct plist *trav;
  26.     float    *xvec, *yvec;
  27.     int       len, i;
  28.     XPoint    p1, p2;
  29.  
  30.     if (reg->r_type == DUBLIN) {
  31.     draw_double_line(reg->r_dlist, reg->r_plist);
  32.     draw_dlist(img_win->d_xid, reg->r_dlist);
  33.     return;
  34.     }
  35.     if (reg->r_flags == LSQ) {
  36.     /* call the measley fit() algorithm */
  37.     len = llist_depth((llist *) reg->r_plist);
  38.     if ((xvec = (float *) malloc(len * sizeof(float))) == NULL) {
  39.         perror("malloc");
  40.         exit(0);
  41.     }
  42.     if ((yvec = (float *) malloc(len * sizeof(float))) == NULL) {
  43.         perror("malloc");
  44.         exit(0);
  45.     }
  46.     for (i = 0, trav = reg->r_plist; trav != NULL; trav = trav->next, i++) {
  47.         xvec[i] = (float) trav->pt.x;
  48.         yvec[i] = (float) trav->pt.y;
  49.     }
  50.     fit(xvec, yvec, len, &p1, &p2);
  51.     free(xvec);
  52.     free(yvec);
  53.     } else {
  54.     if (reg->r_plist == NULL || reg->r_plist->next == NULL)
  55.         return;
  56.     p1.x = reg->r_plist->pt.x;
  57.     p1.y = reg->r_plist->pt.y;
  58.     p2.x = reg->r_plist->next->pt.x;
  59.     p2.y = reg->r_plist->next->pt.y;
  60.     }
  61.     ras_line(p1, p2, (struct dlist *) llist_tail((llist *) reg->r_dlist),
  62.          orig_ximg, orig_img);
  63.     draw_dlist(img_win->d_xid, reg->r_dlist);
  64. }
  65.  
  66. /*****************************************************************/
  67. draw_double_line(dlist, ptlist)
  68.     struct dlist *dlist;
  69.     struct plist *ptlist;
  70. {
  71.     XPoint    p1, p2;
  72.     struct plist *pl;
  73.     struct dlist *seg;
  74.  
  75.     seg = dlist;
  76.     if (seg == NULL)
  77.     return -1;
  78.     pl = ptlist;
  79.     if (pl == NULL)
  80.     return -1;
  81.  
  82.     p1.x = pl->pt.x;
  83.     p1.y = pl->pt.y;
  84.     pl = pl->next;
  85.     if (pl == NULL)
  86.     return -1;
  87.     p2.x = pl->pt.x;
  88.     p2.y = pl->pt.y;
  89.  
  90.     ras_line(p1, p2, seg, orig_ximg, orig_img);
  91.     draw_dlist(img_win->d_xid, dlist);
  92.  
  93.     seg = (struct dlist *) malloc(sizeof(struct dlist));
  94.     seg->next = seg->prev = NULL;
  95.     seg->len = seg->flags = 0;
  96.  
  97.     llist_add((llist *) seg, (llist **) & dlist, (llist **) NULL);
  98.  
  99.     pl = pl->next;
  100.     if (pl == NULL)
  101.     return -1;
  102.  
  103.     p1.x = pl->pt.x;
  104.     p1.y = pl->pt.y;
  105.     pl = pl->next;
  106.     if (pl == NULL)
  107.     return -1;
  108.     p2.x = pl->pt.x;
  109.     p2.y = pl->pt.y;
  110.  
  111.     ras_line(p1, p2, seg, orig_ximg, orig_img);
  112.  
  113.     return(1);
  114. }
  115.  
  116. /*******************************************************************/
  117.  
  118. /* actual line rasterization algorithm (Bresenham) */
  119. ras_line(spt, ept, dlist, bgimg, scimg)
  120.     XPoint    spt, ept;
  121.     struct dlist *dlist;
  122.     XImage   *bgimg;
  123.     struct img_data *scimg;
  124. {
  125.     register int npts, dx, dy;
  126.     register int x1, x2, y1, y2;
  127.     register int yinc, xinc;
  128.     register int err;
  129.     register int x, y;
  130.  
  131.     npts = 0;
  132.     x1 = (int) spt.x;
  133.     y1 = (int) spt.y;
  134.     x2 = (int) ept.x;
  135.     y2 = (int) ept.y;
  136.     dx = x2 - x1;
  137.     dy = y2 - y1;
  138.     if (abs(dx) > abs(dy)) {
  139.     if (dx < 0) {
  140.         x1 = x2;
  141.         x2 = spt.x;
  142.         y1 = y2;
  143.         y2 = spt.y;
  144.     }
  145.     if (y2 > y1)
  146.         yinc = 1;
  147.     else
  148.         yinc = -1;
  149.     /* first octant algorithm */
  150.     err = -(dx / 2);
  151.     x = x1;
  152.     y = y1;
  153.     pvec[npts].pt.x = (short) x;
  154.     pvec[npts].pt.y = (short) y;
  155.     pvec[npts].val = (unsigned char) XGetPixel(bgimg, x, y);
  156.     pvec[npts].oval = dval(x, y, scimg, 0);
  157.     npts++;
  158.     if (npts >= PVEC_SIZE - 1)
  159.         return;
  160.     while (x < x2) {
  161.         err += abs(dy);
  162.         if (err > 0) {
  163.         y += yinc;
  164.         err -= abs(dx);
  165.         }
  166.         x++;
  167.         pvec[npts].pt.x = (short) x;
  168.         pvec[npts].pt.y = (short) y;
  169.         pvec[npts].val = (unsigned char) XGetPixel(bgimg, x, y);
  170.         pvec[npts].oval = dval(x, y, scimg, 0);
  171.         npts++;
  172.         if (npts >= PVEC_SIZE - 1)
  173.         return;
  174.     }
  175.     } else {
  176.     if (dy < 0) {
  177.         x1 = x2;
  178.         x2 = spt.x;
  179.         y1 = y2;
  180.         y2 = spt.y;
  181.     }
  182.     if (x2 > x1)
  183.         xinc = 1;
  184.     else
  185.         xinc = -1;
  186.     /* second octant algorithm. */
  187.     err = -(dy / 2);
  188.     x = x1;
  189.     y = y1;
  190.     pvec[npts].pt.x = (short) x;
  191.     pvec[npts].pt.y = (short) y;
  192.     pvec[npts].val = (unsigned char) XGetPixel(bgimg, x, y);
  193.     pvec[npts].oval = dval(x, y, scimg, 0);
  194.     npts++;
  195.     if (npts >= PVEC_SIZE - 1)
  196.         return;
  197.     while (y < y2) {
  198.         err += abs(dx);
  199.         if (err > 0) {
  200.         x += xinc;
  201.         err -= abs(dy);
  202.         }
  203.         y++;
  204.         pvec[npts].pt.x = (short) x;
  205.         pvec[npts].pt.y = (short) y;
  206.         pvec[npts].val = (unsigned char) XGetPixel(bgimg, x, y);
  207.         pvec[npts].oval = dval(x, y, scimg, 0);
  208.         npts++;
  209.         if (npts >= PVEC_SIZE - 1)
  210.         return;
  211.     }
  212.     }
  213.  
  214.     /* put them in the dlist structure */
  215.     dlist->points = (struct pval *) malloc(sizeof(struct pval) * (npts));
  216.     if (dlist->points == NULL) {
  217.     perror("malloc");
  218.     exit(1);
  219.     }
  220.     dlist->len = npts;
  221.     bcopy((char *) pvec, (char *) dlist->points, sizeof(struct pval) * npts);
  222. }
  223.  
  224. /* This routine was taken from the Numerical Recipes file
  225.  * "fit.c".  I stripped out such things as significance and
  226.  * so on.
  227.  */
  228. fit(x, y, ndata, p1, p2)    /* least squares fit algorithm */
  229.     float     x[], y[];
  230.     int       ndata;
  231.     XPoint   *p1, *p2;
  232. {
  233.     int       i;
  234.     float     t, sxoss, sx = 0.0, sy = 0.0, st2 = 0.0, ss, a, b;
  235.     float     minx = 65535.0, maxx = 0.0;
  236.  
  237.     b = 0.0;
  238.     for (i = 0; i < ndata; i++) {
  239.     sx += x[i];
  240.     sy += y[i];
  241.     if (x[i] < minx)
  242.         minx = x[i];
  243.     if (x[i] > maxx)
  244.         maxx = x[i];
  245.     }
  246.     ss = ndata;
  247.     sxoss = sx / ss;
  248.     for (i = 0; i < ndata; i++) {
  249.     t = x[i] - sxoss;
  250.     st2 += t * t;
  251.     b += t * y[i];
  252.     }
  253.     b = b / st2;
  254.     a = (sy - sx * (b)) / ss;
  255.  
  256.     p1->x = (short) minx;
  257.     p1->y = (short) (a + b * minx);
  258.     p2->x = (short) maxx;
  259.     p2->y = (short) (a + b * maxx);
  260. }
  261.  
  262. /*****************************************************************/
  263.  
  264. char     *
  265. line_info(reg)            /* create string containing message giving
  266.                  * length of a line */
  267.     struct region *reg;
  268. {
  269.     char      mesg[80];
  270.     int       x1, x2, y1, y2;
  271.     double    dist;
  272.  
  273.     if (reg == NULL)
  274.     return (NULL);
  275.     if (reg->r_plist == NULL)
  276.     return (NULL);
  277.     if (reg->r_plist->next == NULL)
  278.     return (NULL);
  279.  
  280.     /* this does not handle LS mode properly yet ! */
  281.  
  282.     x1 = reg->r_plist->pt.x;
  283.     y1 = reg->r_plist->pt.y;
  284.     x2 = reg->r_plist->next->pt.x;
  285.     y2 = reg->r_plist->next->pt.y;
  286.  
  287.     dist = sqrt(pow((double) (x2 - x1), (double) 2) +
  288.         pow((double) (y2 - y1), (double) 2));
  289.  
  290.     sprintf(mesg, "Length of current line is %d pixels ", (int) (dist + .5));
  291.     return (mesg);
  292. }
  293.